#pragma once

namespace My {

template <typename T>
EnumControlBase<T>::EnumControlBase(BasicProperty<T> & p, const EditableList & list) :
	m_Property(p), m_Objects(list)
{
}


template <typename T>
String EnumControlBase<T>::GetItem(My::Size index)
{
	return GetEnumItem(index).name;
}

template <typename T>
bool EnumControlBase<T>::GetCurrent(int & index)
{
	T value;
	bool result = m_Property.GetValue(m_Objects, value);
	for (My::Size i = 0; i < GetItemCount(); ++i)
		if (value == GetEnumItem(i).value) {
			index = int(i);
			return result;
		}
	index = -1;
	return false;
}

template <typename T>
int EnumControlBase<T>::SetCurrent(int index)
{
	if (index != -1)
		m_Property.SetValue(m_Objects, 
			GetEnumItem(index).value);
	return GetCurrent(index) ? index : -1;
}

template <typename T>
void EnumControlBase<T>::HandleUpdateUI()
{
	SetVisible(m_Property.Visible(m_Objects));
	SetEnabled(!m_Property.ReadOnly(m_Objects));
}

// EnumTypeControl

template <typename T>
EnumTypeControl<T>::EnumTypeControl(BasicProperty<T> & p, const EditableList & list, const String & def) :
	EnumControlBase<T>(p, list), m_Default(def)
{
}

template <typename T>
Size EnumTypeControl<T>::GetItemCount()
{
	return sizeof(Items) / sizeof(EnumItem<T>);
}

template <typename T>
String EnumTypeControl<T>::GetDefaultItem()
{
	return m_Default;
}

template <typename T>
EnumItem<T> EnumTypeControl<T>::GetEnumItem(My::Size index)
{
	return Items[index];
}

// EnumPropertyBase

template <typename T>
Widget * EnumPropertyBase<T>::CreateControl(const EditableList & list)
{
	return new EnumPropertyControl<T>(* this, list);
}

template <typename T>
void EnumPropertyBase<T>::FreeControl(Widget * pControl)
{
	delete pControl;
}


// EnumPropertyControl

template <typename T>
EnumPropertyControl<T>::EnumPropertyControl(EnumPropertyBase<T> & p, const EditableList & list) :
	EnumControlBase<T>(p, list), m_Property(p)
{
}

template <typename T>
Size EnumPropertyControl<T>::GetItemCount()
{
	return m_Property.GetItemCount(m_Objects);
}

template <typename T>
String EnumPropertyControl<T>::GetDefaultItem()
{
	return m_Property.GetDefaultItem(m_Objects);
}

template <typename T>
BasicProperty<T> & EnumPropertyControl<T>::GetProperty()
{
	return m_Property;
}

template <typename T>
EnumItem<T> EnumPropertyControl<T>::GetEnumItem(My::Size index)
{
	return m_Property.GetEnumItem(m_Objects, index);
}

// EnumProperty

template <typename T>
EnumProperty<T>::EnumProperty(const EnumItem<T> items[], const String & def)
{	
	Init(items, def);
}

template <typename T>
EnumProperty<T>::EnumProperty() :
	m_pItems(0), m_Count(0)
{
}

template <typename T>
void EnumProperty<T>::Init(const EnumItem<T> items[], const String & def)
{
	m_Count = 0;
	m_pItems = items;
	m_Default = def;
	while (!m_pItems[m_Count].name.empty())
		++m_Count;
}

template <typename T>
Size EnumProperty<T>::GetItemCount(const EditableList &)
{
	return m_Count;
}

template <typename T>
String EnumProperty<T>::GetDefaultItem(const EditableList &)
{
	return m_Default;
}

template <typename T>
EnumItem<T> EnumProperty<T>::GetEnumItem(const EditableList &, Size index)
{
	return m_pItems[index];
}

} // My
